
#include	"Weapon.h"
#include	"Ship.h"
#include	"defs.h"
#include	"SpaceShooter.h"
#include	"Util.h"

Weapon::Weapon(){
	pShip = NULL;
	isFiring = false;
	firingInterval = 0;
	enemyWeapon = false;
}

bool Weapon::init(weaponTypes w, Ship* pShip){

	if(pShip == NULL)
		return false;

	this->pShip = pShip;

	weaponType = w;

	if(enemyWeapon)
		p.invertFireDirection();

	if((projectilesSurface = Surface::OnLoad("images/projectiles.png")) == NULL)
		return false;

	switch(weaponType)
	{
		case PULSE_GUN:

			if(!p.init(Projectile::PULSE, projectilesSurface))
				return false;

			weaponFireRate = PULSE_GUN_RATE;

		break;

		default:
			return false;
	}

	return true;
}

void Weapon::cleanup(){
	
	projectiles.clear();

	if(projectilesSurface)
		SDL_FreeSurface(projectilesSurface);
	
	projectilesSurface = NULL;
}

void Weapon::fire(){

	if(SDL_GetTicks() < firingInterval)
		return;
	else
		firingInterval = SDL_GetTicks() + weaponFireRate;
	
	switch(weaponType)
	{
		case PULSE_GUN:

			p.setPos( pShip->getX() + 23 , pShip->getY() );

			p.setSpeedX(0);
			p.setSpeedY(12);

			projectiles.push_back(p);

		break;
	}
}

void Weapon::loopProjectiles(){

	if(isFiring)
		fire();

	std::deque<Projectile>::iterator i;
	std::vector<std::deque<Projectile>::iterator> elementsToErase;
	
	Ship* playerShip = (Ship*) SpaceShooter::getPlayerShip();

	for(i = projectiles.begin(); i != projectiles.end(); i++)
	{
		i->loop();

		//deletar projetil se fora da tela ou ja deu dano
		if( i->getX() < 0 || i->getX() > WND_WIDTH ||
			i->getY() < 0 || i->getY() > WND_HEIGHT || i->madeDamage)
				elementsToErase.push_back(i);
		else
		{
			SDL_Rect projRect;
			SDL_Rect shipRect;

			projRect.x = i->getX() + i->getColRect().x;
			projRect.y = i->getY() + i->getColRect().y;

			projRect.w = i->getColRect().w;
			projRect.h = i->getColRect().h;

			if(enemyWeapon)
			{
				//check collision
				if(playerShip == NULL)
					return;
				
				shipRect.x = playerShip->getX() + playerShip->getColRect().x;
				shipRect.y = playerShip->getY() + playerShip->getColRect().y;

				shipRect.w = playerShip->getColRect().w;
				shipRect.h = playerShip->getColRect().h;

				if( rectCollided(projRect, shipRect) )
				{
					playerShip->takeShot(i->projectileType);
					i->madeDamage = true;
				}
					
			}
			else
			{
				//Check all objects for collisions
				for(int j=1; j< SpaceShooter::objectList.size(); j++)
				{
					shipRect.x = ((Ship*) SpaceShooter::objectList[j])->getX() + ((Ship*) SpaceShooter::objectList[j])->getColRect().x;
					shipRect.y = ((Ship*) SpaceShooter::objectList[j])->getY() + ((Ship*) SpaceShooter::objectList[j])->getColRect().y;

					shipRect.w = ((Ship*) SpaceShooter::objectList[j])->getColRect().w;
					shipRect.h = ((Ship*) SpaceShooter::objectList[j])->getColRect().h;

					if( rectCollided(projRect, shipRect) )
					{
						((Ship*) SpaceShooter::objectList[j])->takeShot(i->projectileType);
						i->madeDamage = true;
					}
				}
			}
			
		}		
	}

	for(int i=0; i< elementsToErase.size(); i++)
		projectiles.erase(elementsToErase[i]);

	elementsToErase.clear();
}

void Weapon::renderProjectiles(SDL_Surface* destSurface){
	
	std::deque<Projectile>::iterator i;

	for(i = projectiles.begin(); i != projectiles.end(); i++)
		i->render(destSurface);
}

void Weapon::setEnemyWeapon(bool ew){
	enemyWeapon = ew;
}

void Weapon::setFireRate(int fr){
	if(fr > 0)
		weaponFireRate = fr;
}